package com.zkb.modules.job.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zkb.common.util.PageUtil;
import com.zkb.common.util.UUIDUtil;
import com.zkb.common.vo.AjaxResultVo;
import com.zkb.modules.base.BaseController;
import com.zkb.modules.job.model.SysJob;
import com.zkb.modules.job.model.SysJobLog;
import com.zkb.modules.job.service.SysJobLogService;
import com.zkb.modules.job.service.SysJobService;

@Controller
@RequestMapping("/sysJob")
public class SysJobController extends BaseController {

	@Autowired
	private SysJobService sysJobService;

	@Autowired
	private SysJobLogService sysJobLogService;

	/**
	 * 系统工具--定时任务
	 */
	@GetMapping("/toSysJobPage")
	public String sysjobList() {
		return "sysjob/list";
	}

	/**
	 * 系统工具--定时任务日志
	 */
	@GetMapping("/toSysJobLogPage")
	public String sysjobLogList() {
		return "sysjob/loglist";
	}

	/**
	 * 系统工具--定时任务添加cron表达式
	 */
	@GetMapping(value = "/tocron")
	public String tocron() {
		return "sysjob/cron";
	}

	/**
	 * 查询定时任务列表
	 * 
	 * @param sysJob
	 * @param limit
	 * @param offset
	 * @return
	 */
	@RequiresPermissions("sysJob:list")
	@PostMapping("/list")
	@ResponseBody
	public AjaxResultVo pageSysJob(SysJob sysJob, Integer limit, Integer offset, String daterange) {
		try {
			PageHelper.startPage(PageUtil.getPageNo(limit, offset), limit);
			// 日期查询
			String[] dateranges = {};
			if (StringUtils.isNotBlank(daterange)) {
				 dateranges = StringUtils.split(daterange, "~");
			}
			List<SysJob> jobList = sysJobService.listSysJobs(sysJob, dateranges);
			PageInfo<SysJob> pageResult = new PageInfo<>(jobList);
			AjaxResultVo resutlVo = AjaxResultVo.success();
			resutlVo.put("rows", pageResult.getList());
			resutlVo.put("total", pageResult.getTotal());
			return resutlVo;
		} catch (Exception e) {
			logger.error(String.format("定时任务列表查询失败 SysJobController.pageSysJob%s", e));
			return AjaxResultVo.error("查询失败");
		}
	}

	/**
	 * 跳转添加定时任务
	 * 
	 * @return
	 */
	@RequiresPermissions("sysJob:add")
	@GetMapping("/add")
	public String add() {
		return "sysjob/add";
	}

	/**
	 * 添加定时任务
	 * 
	 * @param sysJob
	 * @return
	 */
	@RequiresPermissions("sysJob:add")
	@PostMapping("/addSysJob")
	@ResponseBody
	public AjaxResultVo addSysJob(SysJob sysJob) {
		try {
			sysJob.setJobId(Long.valueOf(UUIDUtil.getUniqueIdByUUId()));
			Date currentDate = new Date();
			sysJob.setCreateTime(currentDate);
			sysJob.setUpdateTime(currentDate);
			int result = sysJobService.insertJob(sysJob);
			if (result > 0) {
				return AjaxResultVo.success("添加任务成功");
			} else {
				return AjaxResultVo.error("添加任务失败");
			}
		} catch (Exception e) {
			logger.error(String.format("定时任务添加失败 SysJobController.addSysJob%s", e));
			return AjaxResultVo.error("添加任务失败");
		}
	}

	/**
	 * 定时任务详情页
	 * 
	 * @param model
	 * @param jobId
	 * @return
	 */
	@RequiresPermissions("sysJob:edit")
	@GetMapping("/editSysJob")
	public String detail(Model model, String jobId) {
		SysJob sysJob = sysJobService.getSysJobById(Long.valueOf(jobId));
		model.addAttribute("sysJob", sysJob);
		return "sysjob/detail";
	}

	/**
	 * 修改定时任务
	 * 
	 * @param sysJob
	 * @return
	 */
	@RequiresPermissions("sysJob:edit")
	@PostMapping("/editSysJob")
	@ResponseBody
	public AjaxResultVo editSysJob(@ModelAttribute("sysJob") SysJob sysJob) {
		try {
			Date currentDate = new Date();
			sysJob.setUpdateTime(currentDate);
			int result = sysJobService.updateJob(sysJob);
			if (result > 0) {
				return AjaxResultVo.success("编辑任务成功");
			} else {
				return AjaxResultVo.error("编辑任务失败");
			}
		} catch (Exception e) {
			logger.error(String.format("定时任务编辑失败 SysJobController.editSysJob%s", e));
			return AjaxResultVo.error("编辑任务失败");
		}
	}

	/**
	 * 批量删除定时任务
	 * 
	 * @param jobIdStr
	 * @return
	 */
	@RequiresPermissions("sysJob:delete")
	@PostMapping("/batchDelete")
	@ResponseBody
	public AjaxResultVo batchDelete(String jobIdStr) {
		try {
			sysJobService.deleteJobByIds(jobIdStr);
			return AjaxResultVo.success("删除成功");
		} catch (Exception e) {
			logger.error(String.format("定时任务批量删除失败 SysJobController.batchDelete%s", e));
			return AjaxResultVo.error("删除失败");
		}
	}

	/**
	 * 删除定时任务
	 * 
	 * @param jobId
	 * @return
	 */
	@RequiresPermissions("sysJob:delete")
	@PostMapping("/deleteSysJob")
	@ResponseBody
	public AjaxResultVo delete(String jobId) {
		try {
			sysJobService.deleteJobByIds(jobId);
			return AjaxResultVo.success("删除成功");
		} catch (Exception e) {
			logger.error(String.format("定时任务单条删除失败 SysJobController.delete%s", e));
			return AjaxResultVo.error("删除失败");
		}
	}

	/**
	 * 批量删除定时任务日志
	 * 
	 * @param jobLogIdStr
	 * @return
	 */
	@RequiresPermissions("sysJob:delete")
	@PostMapping("/logBatchDelete")
	@ResponseBody
	public AjaxResultVo logBatchDelete(String jobLogIdStr) {
		try {
			sysJobLogService.deleteJobLogByIds(jobLogIdStr);
			return AjaxResultVo.success("删除成功");
		} catch (Exception e) {
			logger.error(String.format("定时任务日志批量删除失败 SysJobController.logBatchDelete%s", e));
			return AjaxResultVo.error("删除失败");
		}
	}

	/**
	 * 变更定时任务日志状态
	 * 
	 * @param job
	 * @return
	 */
	@RequiresPermissions("sysJob:edit")
	@PostMapping("/changeStatus")
	@ResponseBody
	public AjaxResultVo changeStatus(SysJob job) {
		try {
			SysJob newJob = sysJobService.getSysJobById(job.getJobId());
			newJob.setStatus(job.getStatus());
			int result = sysJobService.changeStatus(newJob);
			if (result > 0) {
				return AjaxResultVo.success("修改成功");
			} else {
				return AjaxResultVo.error("修改失败");
			}
		} catch (Exception e) {
			logger.error(String.format("定时任务状态变更失败 SysJobController.changeStatus%s", e));
			return AjaxResultVo.error("修改失败");
		}
	}

	/**
	 * 运行定时任务
	 * 
	 * @param job
	 * @return
	 */
	@RequiresPermissions("sysJob:edit")
	@PostMapping("/runSysJob")
	@ResponseBody
	public AjaxResultVo runSysJob(SysJob job) {
		try {
			sysJobService.run(job);
			return AjaxResultVo.success("任务运行成功");
		} catch (Exception e) {
			logger.error(String.format("定时任务运行失败 SysJobController.runSysJob%s", e));
			return AjaxResultVo.error("任务运行失败");
		}
	}

	/**
	 * corn表达式运行
	 * 
	 * @param expression
	 * @return
	 */
	@RequestMapping(value = "/calcRunTime")
	@ResponseBody
	public Object calcRunTime(String expression) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
		StringBuffer sbResult = new StringBuffer();
		sbResult.append("[");
		try {
			CronTriggerImpl trigger = new CronTriggerImpl();
			trigger.setCronExpression(expression);
			Date start = trigger.getStartTime();
			for (int i = 0; i < 5; i++) {
				Date next = trigger.getFireTimeAfter(start);
				sbResult.append(", \"").append(sdf.format(next)).append("\"");
				start = next;
			}
			sbResult.append("]");
		} catch (ParseException e) {
			sbResult.append("cron表达式错误！");
			sbResult.append("]");
			return sbResult;
		}
		return sbResult.replace(sbResult.indexOf(","), sbResult.indexOf(",") + 1, "");
	}

	/**
	 * 定时任务日志列表
	 * 
	 * @param sysJobLog
	 * @param limit
	 * @param offset
	 * @return
	 */
	@RequiresPermissions("sysJob:list")
	@PostMapping("/jobloglist")
	@ResponseBody
	public AjaxResultVo pageJobLoglist(SysJobLog sysJobLog, Integer limit, Integer offset, String daterange) {
		try {
			PageHelper.startPage(PageUtil.getPageNo(limit, offset), limit);
			// 日期查询
			String[] dateranges = {};
			if (StringUtils.isNotBlank(daterange)) {
				 dateranges = StringUtils.split(daterange, "~");
			}
			List<SysJobLog> jobLogList = sysJobLogService.listSysLogJobs(sysJobLog, dateranges);
			PageInfo<SysJobLog> pageResult = new PageInfo<>(jobLogList);
			AjaxResultVo resultVo = AjaxResultVo.success();
			resultVo.put("rows", pageResult.getList());
			resultVo.put("total", pageResult.getTotal());
			return resultVo;
		} catch (Exception e) {
			logger.error(String.format("定时任务日志列表查询失败 SysJobController.pageJobLoglist%s", e));
			return AjaxResultVo.error("查询失败");
		}
	}

	/**
	 * 定时任务运行详情
	 * 
	 * @param model
	 * @param jobLogId
	 * @return
	 */
	@GetMapping("/jobloginfo")
	public String jobloginfo(Model model, String jobLogId) {
		SysJobLog sysJobLog = sysJobLogService.getSysJobLogById(Long.valueOf(jobLogId));
		model.addAttribute("sysJobLog", sysJobLog);
		return "sysjob/logdetail";
	}

}
